package com.kingint.web.portal.serve.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonObject;
import com.kingint.mbg.bas.entity.BasRoom;
import com.kingint.mbg.bas.entity.BasServiceClass;
import com.kingint.mbg.bas.mapper.BasRoomMapper;
import com.kingint.mbg.data.entity.DataCustomerPreference;
import com.kingint.mbg.ser.entity.*;
import com.kingint.mbg.ser.mapper.SerReceiveWorkMiddleMapper;
import com.kingint.mbg.ser.mapper.SerServiceOrderMapper;
import com.kingint.mbg.ser.mapper.SerServiceOrderMiddleMapper;
import com.kingint.mbg.ser.mapper.SerWorkOrderMapper;
import com.kingint.mbg.sys.entity.UmsMember;
import com.kingint.mbg.sys.mapper.UmsMemberMapper;
import com.kingint.web.admin.base.service.BasOrderTypeHotelTimeService;
import com.kingint.web.admin.serve.service.SerReceiveWorkMiddleService;
import com.kingint.web.portal.base.service.WorkOrderTypeService;
import com.kingint.web.portal.data.service.DataCustomerPreferenceService;
import com.kingint.web.portal.data.service.DataHouseServicesService;
import com.kingint.web.portal.data.service.DataWorkOrderService;
import com.kingint.web.portal.serve.service.ActivitiCancelService;
import com.kingint.web.portal.serve.service.ServiceOrderService;
import com.kingint.web.sys.service.UmsAdminService;
import com.kingint.web.util.CharUtil;
import com.kingint.web.util.WorkType;
import com.kingint.web.util.WorkTypeUtil;
import com.kingint.web.util.spring.SpringContextHolder;
import com.kingint.web.vo.CountParam;
import com.kingint.web.vo.ServiceOrderBean;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class ServiceOrderServiceImpl implements ServiceOrderService {

    @Resource
    private UmsAdminService adminService;
    @Resource
    private SerServiceOrderMapper serServiceOrderMapper;
    @Resource
    private SerWorkOrderMapper workOrderMapper;
    @Resource
    private BasRoomMapper basRoomMapper;
    @Resource
    private SerServiceOrderMiddleMapper serServiceOrderMiddleMapper;
    @Resource
    private UmsMemberMapper memberMapper;
    @Resource
    private ActivitiCancelService activitiCancelService;
    @Resource
    private ServiceOrderBean serviceOrderBean;
    @Resource
    private TaskService taskService;
    @Resource
    private SerReceiveWorkMiddleService receiveWorkMiddleService;
    @Resource
    private SerReceiveWorkMiddleMapper receiveWorkMiddleMapper;
    @Resource
    private WorkOrderTypeService workOrderTypeService;

    @Resource
    private BasOrderTypeHotelTimeService basOrderTypeHotelTimeService;
    @Resource
    private DataWorkOrderService dataWorkOrderService;
    @Resource
    private DataHouseServicesService dataHouseServices;
    @Resource
    private DataCustomerPreferenceService dataCustomerPreferenceService;


    @Override
    public int insertServiceOrderInfo(SerServiceOrder serServiceOrder) {
        //插入相关的信息
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("相关账号没有关联酒店id");
            return 0;
        }
        SerWorkOrder workOrder = new SerWorkOrder();
        BeanUtils.copyProperties(serServiceOrder, workOrder);
        workOrder.setCreateTime(new Date());
        Integer typeId = WorkTypeUtil.getWorkTypeIdByName(WorkType.serviceOrderName);
        workOrder.setWorkTypeId(typeId);
        workOrder.setHotelId(hotelId);
        workOrder.setSubmitUserId(currentMember.getId());
        workOrder.setOrderSn(CharUtil.generateOrderSn());//工单号

        //插入总工单中
        int insert = workOrderMapper.insert(workOrder);

        serServiceOrder.setWorkId(workOrder.getId());
        //处理相关的服务内容
        List<BasServiceClass> serviceClassList = serServiceOrder.getServiceClassList();
        if (!CollectionUtils.isEmpty(serviceClassList)) {
            Object o = JSONObject.toJSON(serviceClassList);
            serServiceOrder.setServiceClassContent(o.toString());
        }
        serServiceOrder.setCreateTime(new Date());
        serServiceOrderMapper.insert(serServiceOrder);

        Long handleUserId = serServiceOrder.getHandleUserId();
        int orderStatus = 1;
        if (!StringUtils.isEmpty(handleUserId)) {
            //插入处理人与服务工单中间表
            SerServiceOrderMiddle middle = new SerServiceOrderMiddle();
            middle.setCreateTime(new Date());
            middle.setHandleUserId(serServiceOrder.getHandleUserId());
            middle.setServiceOrderId(serServiceOrder.getId());
            serServiceOrderMiddleMapper.insert(middle);

            //添加总的接单中间表
            SerReceiveWorkMiddle workMiddle = new SerReceiveWorkMiddle();
            workMiddle.setReceiveUserId(handleUserId);
            workMiddle.setWorkId(workOrder.getId());
            receiveWorkMiddleService.insertReceiveWorkInfo(workMiddle);
            orderStatus = 6;
        }
        //启动相关流程
        String businessKey = serviceOrderBean.getProcessInstanceKey() + "_" + currentMember.getHotelId() + "_" + workOrder.getId();//业务相关参数
        HashMap<String, Object> map = new HashMap<>();
        map.put(serviceOrderBean.getCreateNameEl(), currentMember.getUsername());
        String processInstanceId = activitiCancelService.startProcess(serviceOrderBean.getProcessInstanceKey(), businessKey, map);
        workOrder.setProcessInstanceId(processInstanceId);
        workOrder.setOrderStatus(orderStatus);
        workOrderMapper.updateById(workOrder);

        //工单上报计时
        basOrderTypeHotelTimeService.addtim(currentMember.getHotelId(), workOrder.getId(), WorkType.serviceOrderName,new Date().getTime());

        //住客统计
        dataHouseServices.addDataHouseInfo(currentMember.getHotelId(), CountParam.SERVICECOUNT, serServiceOrder.getRoomId(), serServiceOrder.getRoomNum());

        //总工单统计
        dataWorkOrderService.addwork(currentMember.getHotelId(),CountParam.SERVICECOUNT);

        List<BasServiceClass> basServiceClassesList = JSONObject.parseArray(serServiceOrder.getServiceClassContent(),BasServiceClass.class);
        //服务工单统计
        for (BasServiceClass b :basServiceClassesList) {
            dataCustomerPreferenceService.addDataHouseInfo(currentMember.getHotelId(),b.getId(),b.getName());
        }
        return insert;
    }


    @Override
    public List<SerServiceOrder> stayHandleServiceOrder() {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("相关账号没有关联酒店id");
            return null;
        }
        List<SerServiceOrder> allServiceOrderList = serServiceOrderMapper.getAllServiceOrderList(hotelId, currentMember.getId(), 2);
        return allServiceOrderList;
    }

    @Override
    public SerServiceOrder getServiceOrderDetails(Integer id) {
        SerServiceOrder serServiceOrder = serServiceOrderMapper.selectById(id);
        Integer workId = serServiceOrder.getWorkId();
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        serServiceOrder.setOrderSn(serWorkOrder.getOrderSn());//工单号
        serServiceOrder.setHotelId(serWorkOrder.getHotelId());//酒店id
        serServiceOrder.setRoomId(serWorkOrder.getRoomId());//房间id

        serServiceOrder.setOrderStatus(serWorkOrder.getOrderStatus());//工单状态
        BasRoom basRoom = basRoomMapper.selectById(serWorkOrder.getRoomId());
        serServiceOrder.setRoomNum(basRoom.getRoomNum());//房间号

        //服务内容
        String content = serServiceOrder.getServiceClassContent();
        if (!StringUtils.isEmpty(content)) {
            List<BasServiceClass> list = JSONObject.parseArray(content, BasServiceClass.class);
            serServiceOrder.setServiceClassList(list);
        }
        //处理人
        QueryWrapper<SerServiceOrderMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("service_order_id", serServiceOrder.getId())
                .eq("status", 0);
        SerServiceOrderMiddle one = serServiceOrderMiddleMapper.selectOne(wrapper);
        if (!StringUtils.isEmpty(one)) {
            Long handleUserId = one.getHandleUserId();
            UmsMember umsMember = memberMapper.selectById(handleUserId);
            serServiceOrder.setHandleName(umsMember.getUsername());
        }
        return serServiceOrder;
    }

    @Override
    public List<SerServiceOrder> stayConfirmServiceOrder() {
        UmsMember currentMember = adminService.getCurrentMember();
        Integer hotelId = currentMember.getHotelId();
        if (StringUtils.isEmpty(hotelId)) {
            log.debug("相关账号没有关联酒店id");
            return null;
        }
        List<SerServiceOrder> allServiceOrderList = serServiceOrderMapper.getAllServiceOrderList(hotelId, currentMember.getId(), 6);
        return allServiceOrderList;
    }

    @Override
    public int confirmServiceOrder(Integer id) {
        UmsMember currentMember = adminService.getCurrentMember();
        SerServiceOrder serviceOrder = serServiceOrderMapper.selectById(id);
        Integer workId = serviceOrder.getWorkId();
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        Task task = taskService.createTaskQuery()
                .processInstanceId(serWorkOrder.getProcessInstanceId())
                .singleResult();

        if (!StringUtils.isEmpty(task)) {
            HashMap<String, Object> map = new HashMap<>();
            map.put(serviceOrderBean.getHandleUserEl(), currentMember.getUsername());
            taskService.complete(task.getId(), map);
            return 1;
        }
        log.debug("没有查询到对应的流程实例");
        return 0;
    }

    @Override
    public int finishServiceOrder(Integer id) {
        UmsMember currentMember = adminService.getCurrentMember();
        SerServiceOrder serviceOrder = serServiceOrderMapper.selectById(id);
        Integer workId = serviceOrder.getWorkId();
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        Integer orderStatus = serviceOrder.getOrderStatus();
        if(orderStatus==4){
            log.debug("挂起状态不能完成当前工单");
            return -1;
        }
        Task task = taskService.createTaskQuery()
                .processInstanceId(serWorkOrder.getProcessInstanceId())
                .singleResult();

        if (!StringUtils.isEmpty(task)) {
            HashMap<String, Object> map = new HashMap<>();
            map.put(serviceOrderBean.getCompleteStatus(), 1);
            taskService.setVariables(task.getId(), map);
            taskService.complete(task.getId());

            basOrderTypeHotelTimeService.deltim(currentMember.getHotelId(),workId,WorkType.serviceOrderName);

            //同时判断是否超时
            workOrderTypeService.judgeWorkOrderIsTimeOut(currentMember.getId(), workId, WorkType.serviceOrderName);
            return 1;
        }
        log.debug("没有查询到对应的流程实例");
        return 0;
    }

    /**
     * 挂起此单
     *
     * @param id
     * @return
     */
    @Override
    public int hangUpOrder(Integer id) {
        SerServiceOrder serviceOrder = serServiceOrderMapper.selectById(id);
        Integer workId = serviceOrder.getWorkId();
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        Integer orderStatus = serWorkOrder.getOrderStatus();
        if (orderStatus == 4) {//挂起
            log.info("已经挂起当前单");
            return 0;
        }
        Task task = taskService.createTaskQuery()
                .processInstanceId(serWorkOrder.getProcessInstanceId())
                .singleResult();
        if (!StringUtils.isEmpty(task)) {//挂起
            String name = task.getName();//判断当前状态
            if (name.equals(serviceOrderBean.getCreateName())) {//创建节点 直接修改当前的状态
                handleDeleteServiceMiddle(id, workId);
                //同时修改总单状态
                SerWorkOrder workOrder = new SerWorkOrder();
                workOrder.setId(workId);
                workOrder.setOrderStatus(4);//挂起
                workOrderMapper.updateById(workOrder);
            } else {
                HashMap<String, Object> map = new HashMap<>();
                map.put(serviceOrderBean.getCompleteStatus(), 2);//挂起此单
                taskService.setVariables(task.getId(), map);
                taskService.complete(task.getId());
            }
            return 1;
        }
        log.debug("没有查询到对应的流程实例");
        return 0;
    }

    /**
     * 处理删除中间表
     *
     * @param id
     * @param workId
     */
    private void handleDeleteServiceMiddle(Integer id, Integer workId) {
        QueryWrapper<SerServiceOrderMiddle> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("service_order_id", id);
        SerServiceOrderMiddle orderMiddle = new SerServiceOrderMiddle();
        orderMiddle.setStatus(1);
        serServiceOrderMiddleMapper.update(orderMiddle, queryWrapper);

        //修改中间表 删除之前的
        QueryWrapper<SerReceiveWorkMiddle> wrapper = new QueryWrapper<>();
        wrapper.eq("work_id", workId);
        SerReceiveWorkMiddle workMiddle = new SerReceiveWorkMiddle();
        workMiddle.setStatus(1);
        workMiddle.setIsReplace(1);//更换处理人
        receiveWorkMiddleMapper.update(workMiddle, wrapper);
    }

    //更换处理人
    @Override
    public int changeHandleUser(Integer id, Long memberId) {
        //查询用户信息
        SerServiceOrder serviceOrder = serServiceOrderMapper.selectById(id);
        Integer workId = serviceOrder.getWorkId();
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        Task task = taskService.createTaskQuery()
                .processInstanceId(serWorkOrder.getProcessInstanceId())
                .singleResult();
        if (!StringUtils.isEmpty(task)) {
            String name = task.getName();
            String handleUser = serviceOrderBean.getHandleUser();
            if (name.equals(handleUser)) {//处理人员节点 在处理的阶段
                HashMap<String, Object> map = new HashMap<>();
                map.put(serviceOrderBean.getCompleteStatus(), 2);//挂起此单
                taskService.setVariables(task.getId(), map);
                taskService.complete(task.getId());
                //同时修改总单状态
                SerWorkOrder workOrder = new SerWorkOrder();
                workOrder.setId(workId);
                workOrder.setOrderStatus(6);
                workOrderMapper.updateById(workOrder);
                //同时执行到下一个节点
            } else if (name.equals(serviceOrderBean.getCreateName())) {//创建工单节点，删除对应的当前工单的其他接单人员（待确认的更换
                handleDeleteServiceMiddle(id, workId);
                //同时修改总单状态
                SerWorkOrder workOrder = new SerWorkOrder();
                workOrder.setId(workId);
                workOrder.setOrderStatus(6);
                workOrderMapper.updateById(workOrder);
            }
            //添加接收人中间表
            SerServiceOrderMiddle orderMiddle = new SerServiceOrderMiddle();
            orderMiddle.setServiceOrderId(id);
            orderMiddle.setHandleUserId(memberId);
            orderMiddle.setCreateTime(new Date());
            serServiceOrderMiddleMapper.insert(orderMiddle);

            //添加ser_receive_work_middle中间表
            SerReceiveWorkMiddle workMiddle = new SerReceiveWorkMiddle();
            workMiddle.setReceiveUserId(memberId);
            workMiddle.setWorkId(workId);
            receiveWorkMiddleService.insertReceiveWorkInfo(workMiddle);
            return 1;
        }
        log.debug("没有查询到对应的流程实例");
        return 0;
    }

    @Override
    public Integer receiverServiceOrder(Integer id) {
        UmsMember currentMember = adminService.getCurrentMember();
        SerServiceOrder serviceOrder = serServiceOrderMapper.selectById(id);

        //添加中间表 ser_receive_work_middle 维修人员接受
        SerReceiveWorkMiddle middle = new SerReceiveWorkMiddle();
        middle.setWorkId(serviceOrder.getWorkId());
        middle.setReceiveUserId(currentMember.getId());
        receiveWorkMiddleService.insertReceiveWorkInfo(middle);

        //添加接单人中间表ser_receive_work_middle
        SerServiceOrderMiddle orderMiddle = new SerServiceOrderMiddle();
        orderMiddle.setServiceOrderId(id);
        orderMiddle.setHandleUserId(currentMember.getId());
        orderMiddle.setCreateTime(new Date());
        serServiceOrderMiddleMapper.insert(orderMiddle);

        Integer workId = serviceOrder.getWorkId();
        SerWorkOrder serWorkOrder = workOrderMapper.selectById(workId);
        Task task = taskService.createTaskQuery()
                .processInstanceId(serWorkOrder.getProcessInstanceId())
                .singleResult();

        if (!StringUtils.isEmpty(task)) {
            HashMap<String, Object> map = new HashMap<>();
            map.put(serviceOrderBean.getHandleUserEl(), currentMember.getUsername());
            taskService.complete(task.getId(), map);
            //同时将信息存入redis
            
            return 1;
        }
        return 0;
    }
}
